<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="shortcut icon" type="image/x-icon" href="../favicon.ico"/>
    <title>为什么需要 #define 声明变量类型？ jetbrick-template</title>

    <link href="../assets/css/application.min.css" rel="stylesheet" type="text/css"/>

    <!--[if lt IE 9]><script src="../assets/js/html5shiv.js"></script><![endif]-->
    <script type="text/javascript" src="../assets/js/application.min.js"></script>
</head>

<body>
<a href="https://github.com/subchen/jetbrick-template/" target="_blank">
    <img src="../assets/images/forkme_right_orange.png" alt="Fork me on GitHub" class="fork-me-on-github">
</a>

<div class="jb-topbar">
    <div class="container">
        <a href="http://subchen.github.io/"><img src="../assets/images/logo-mini.png"/></a>
        <!--
        <ul class="menubar">
            <li><a href="">commons</a></li>
            <li><a href="">webmvc</a></li>
            <li><a href="">template</a></li>
            <li><a href="">orm</a></li>
            <li><a href="">widget</a></li>
            <li><a href="">javadoc-chm</a></li>
        </ul>
        -->
        <div class="pull-right" style="color:#fff;line-height:40px;font-size:16px;padding-right:20px">QQ 交流圈：310491655</div>
    </div>
</div>

<div class="jb-banner">
    <div class="container">
        <a href="http://subchen.github.io/jetbrick-template/index.html">
            <img src="../assets/images/jetbrick-template-logo.png" class="pull-left" />
        </a>
        <ul class="description">
            <li>1. 全新一代 Java 模板引擎</li>
            <li>2. 具有高性能、高扩展性</li>
            <li>3. 完美替代 JSP, Velocity 等引擎模板</li>
        </ul>
        <a href="download/jetbrick-template-1.2.3.zip" class="download-button">
            <img src="../assets/images/download.png"/>
            <span>jetbrick-template-1.2.3.zip<br/>2014-03-10</span>
        </a>
    </div>
</div>

<div class="container">
    <div class="jb-section">
        <ul class="tabs">
            <li><a href="overview.html">简介</a></li>
            <li><a href="download.html">下载</a></li>
            <li><a href="userguide.html">开发指南</a></li>
            <li><a href="config.html">配置指南</a></li>
            <li><a href="syntax.html">语法指南</a></li>
            <li><a href="integrate.html">Web 框架集成</a></li>
            <!--
            <li><a href="example.html">例子</a></li>
            -->
            <li><a href="faq.html" class="selected">FAQ</a></li>
            <li><a href="about.html">关于</a></li>
        </ul>
    </div>
</div>

<div class="container">
    <div class="announcement">
        <a href="download.html#version">2014-03-10：jetbrick-template-1.2.3 正式版已发布，欢迎下载。</a>
    </div>
</div>

<div class="container">


    <div class="markdown">

<!-- markdown body begin -->
	<ul> 
 <li><a href="faq-compile.html">jetbrick-template 将模板编译成 Java Class 有什么好处？</a></li> 
 <li><a href="faq-define.html">jetbrick-template 中为什么需要 #define 声明变量类型？</a></li> 
 <li><a href="faq-error.html">jetbrick-template 常见错误分析</a></li> 
 <li><a href="faq-autoscan.html">jetbrick-template 如何让自动扫描发现用户自定义的扩展方法/函数/标签 Class</a></li> 
 <li><a href="faq-include.html">jetbrick-template 中如何嵌入子模板？（父子间参数传递）</a></li> 
 <li><a href="faq-tag.html">jetbrick-template 中如何自定义 Tag？</a></li> 
 <li><a href="faq-layout.html">jetbrick-template 中如何实现 layout 功能？</a></li> 
 <li><a href="faq-spring.html">jetbrick-template 在 Spring 中的集成方法</a></li> 
</ul>

    <h1><a name="x1330656145"></a><span>1 jetbrick-template 中为什么需要 #define 声明变量类型？</span></h1>
<p>由于 jetbrick-template 将模板编译成 Java Class 来提高模板的运行性能。所以模板在运行之前需要像 JSP 一样，先进行编译。</p>
<p>jetbrick-template 编译的时候，需要确定变量的类型来消除反射和类型转换。(注意： JSP 的 EL 表达式是通过反射解释执行的，不需要在编译期间确定变量的类型)</p>
<p>jetbrick-template 支持类型推导，但是如果无法进行类型推导的时候，就会默认对象的类型是 Object，那么如果需要调用非 Object 对象的属性或者方法的时候，就需要借助 #define 或者 #set 指令来进行变量类型的声明。</p>
<p>如何获取变量的类型：</p> 
<ol> 
 <li>全局默认导入的变量类型，如 <code>context</code>， <code>request</code>， <code>session</code> 等</li> 
 <li>全局 <code>import.variables</code> 中定义的变量类型</li> 
 <li><code>obj.foo</code> 对应的属性类型</li> 
 <li><code>obj.method()</code> 对应的方法返回值</li> 
 <li>扩展函数、扩展方法的返回值</li> 
 <li>其他运算结果</li> 
</ol>
<p>注意： 由于 Java 泛型采用的是类型消除（伪泛型），所以对于 Java 泛型的类型推导在一些情况下是不工作的，这时就需要用 <code>#set(type name = expression)</code> 将中间结果定义为一个类型。也可以用强制类型转换：<code>((String)(obj.items.get(0)).toUpperCase()</code>。</p>
<p>一般在下列情况需要 #define 类型声明</p> 
<ul> 
 <li><code>${bar.foo}</code> 读取 foo 属性</li> 
 <li><code>${bar.foo()}</code> 调用 foo() 方法</li> 
 <li><code>${fnCall(bar)}</code> 调用 fnCall() 函数扩展</li> 
</ul>
<p>下列情况不需要 <code>#define</code> 类型声明</p> 
<ul> 
 <li><code>${bar}</code> 直接输出对象</li> 
 <li><code>#for (type var : items)</code> #for 指令的循环对象 items</li> 
</ul>
<p>我们建议每个模板中所有的 <code>#define</code> 语句都统一定义在文件开头位置，这样方便我们知道模板依赖的各种变量。</p>
<p><code>#define</code> 指令是声明哪些全局 <code>contex</code>t 的变量类型，如果需要指定中间运算结果的变量类型，请用 <code>#set</code> 指令。</p>

<!-- markdown body end -->

    </div>
</div>

<div class="container">
    <div class="jb-footer">
        Copyright 2010-2014 Guoqiang Chen. All rights reserved.
        <br/>subchen&#64;gmail.com, QQ 交流圈：310491655
    </div>
</div>

<style type="text/css">
#cnzz_stat_icon_1000210720 {
	display: none;
}
</style>
<script type="text/javascript">
var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cspan id='cnzz_stat_icon_1000210720'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s22.cnzz.com/z_stat.php%3Fid%3D1000210720' type='text/javascript'%3E%3C/script%3E"));
</script>



</body>
</html>
